﻿
namespace Sai.Test.Rules
{
    using System.Linq;
	using Sai.Core;
	using Sai.Core.Rules;
	using Sai.Test.TestDataBuilders;
	using Xunit;
    using NSubstitute;
    using Sai.Test.XUnit;

	public class CheckEnumValuesFacts
	{
		[Fact, TouchingFileSystemTest]
		public void Removing_Value_From_End_Of_Enum_Is_Flagged()
		{
			var oldEnumBuilder = CompilableEnumBuilder.PublicEnum()
										.Named("Numbers")
										.WithValue("Zero")
										.WithValue("One")
										.WithValue("Two");

            string oldCode = BoilerPlateCodeBuilder.BuildFor(oldEnumBuilder);

			var newEnumBuilder = CompilableEnumBuilder.PublicEnum()
                                        .Named("Numbers")
										.WithValue("Zero")
										.WithValue("One");

            string newCode = BoilerPlateCodeBuilder.BuildFor(newEnumBuilder);

            IProductReleaseProject project = Mock.MinimalProject();

			TypeDifference diff = TypeDifferenceBuilder.Differences()
                .CodeWas(oldCode)
                .CodeIsNow(newCode)
                .CheckedUsing(new CheckEnumValues())
                .Build();

			Assert.True(diff.HasChanged);

            Assert.Equal(1, diff.ValuesRemoved.Count);
            Assert.Null(diff.ValuesAdded);
            Assert.Equal(TypeChangeReason.ValueRemoved, diff.ValuesRemoved.First().Reason);
		}

        [Fact, TouchingFileSystemTest]
        public void Adding_Value_At_End_Is_Flagged()
        {
            var oldEnumBuilder = CompilableEnumBuilder.PublicEnum()
                                        .Named("Numbers")
                                        .WithValue("Zero")
                                        .WithValue("One");

            string oldCode = BoilerPlateCodeBuilder.BuildFor(oldEnumBuilder);

            var newEnumBuilder = CompilableEnumBuilder.PublicEnum()
                                        .Named("Numbers")
                                        .WithValue("Zero")
                                        .WithValue("One")
                                        .WithValue("Two");

            string newCode = BoilerPlateCodeBuilder.BuildFor(newEnumBuilder);

            IProductReleaseProject project = Mock.MinimalProject();

            TypeDifference diff = TypeDifferenceBuilder.Differences()
                .CodeWas(oldCode)
                .CodeIsNow(newCode)
                .CheckedUsing(new CheckEnumValues())
                .Build();

            Assert.True(diff.HasChanged);

            Assert.Equal(1, diff.ValuesAdded.Count);
            Assert.Null(diff.ValuesRemoved);
            Assert.Equal(TypeChangeReason.ValueAdded, diff.ValuesAdded.First().Reason);
        }

        [Fact, TouchingFileSystemTest]
        public void Adding_Value_At_Front_Maintaing_Values_Is_Flagged()
        {
            var oldEnumBuilder = CompilableEnumBuilder.PublicEnum()
                                        .Named("Numbers")
                                        .WithValue("One", 1)
                                        .WithValue("Two", 2);

            string oldCode = BoilerPlateCodeBuilder.BuildFor(oldEnumBuilder);

            var newEnumBuilder = CompilableEnumBuilder.PublicEnum()
                                        .Named("Numbers")
                                        .WithValue("Zero", 0)
                                        .WithValue("One", 1)
                                        .WithValue("Two", 2);

            string newCode = BoilerPlateCodeBuilder.BuildFor(newEnumBuilder);

            IProductReleaseProject project = Mock.MinimalProject();

            TypeDifference diff = TypeDifferenceBuilder.Differences()
                .CodeWas(oldCode)
                .CodeIsNow(newCode)
                .CheckedUsing(new CheckEnumValues())
                .Build();

            Assert.True(diff.HasChanged);

            Assert.Equal(1, diff.ValuesAdded.Count);
            Assert.Null(diff.ValuesRemoved);
            Assert.Equal(TypeChangeReason.ValueAdded, diff.ValuesAdded.First().Reason);
        }

	}
}
